﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;

using NHibernate;
using NHibernate.Cfg;
using NHibernate.Context;

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;

using AutoMapper;

using SAKS.Models;
using SAKS.ViewModels;

namespace SAKS
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            //routes.MapRoute(
            //    "User",
            //    "User/{username}",
            //    new { controller = "User", action = "Index", username = UrlParameter.Optional }
            //    );

            //routes.MapRoute(
            //    "Project",
            //    "Project/{id}",
            //    new { controller = "Project", action = "Details" },
            //    new { id = @"\d+" }
            //    );

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            log4net.Config.XmlConfigurator.Configure();
            ConfigureIoC();
        }

        /// <summary>
        /// 用户登陆时，系统会将用户的角色信息写入Ticket中。如果用户选择下次自动登陆，
        /// 角色信息仍然存在Ticket中，但Asp.net mvc不会自动提取它，所以要在权限验证这步中
        /// 将角色信息提取出来并重建User.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_AuthenticateRequest(Object sender, EventArgs e)
        {
            if (Context.User != null)
            {
                var id = Context.User.Identity as FormsIdentity;
                if (id != null && id.IsAuthenticated)
                {
                    var roles = id.Ticket.UserData.Split(',');
                    Context.User = new System.Security.Principal.GenericPrincipal(id, roles);
                }
            }
        }

        private void ConfigureIoC()
        {
            IUnityContainer container = new UnityContainer().LoadConfiguration();
            container.RegisterType<IControllerActivator, MyControllerActivator>();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }

        public static ISessionFactory SessionFactory = CreateSessionFactory();

        protected static ISessionFactory CreateSessionFactory()
        {
            return new Configuration().Configure().BuildSessionFactory();
        }

        public static ISession CurrentSession
        {
            get { return (ISession)HttpContext.Current.Items["current.session"]; }
            set { HttpContext.Current.Items["current.session"] = value; }
        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            CurrentSession = SessionFactory.OpenSession();
        }

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            if (CurrentSession != null)
                CurrentSession.Dispose();
        }
    }
}